/*
 *  Jajuk
 *  Copyright (C) 2003-2008 The Jajuk Team
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License
 *  as published by the Free Software Foundation; either version 2
 *  of the License, or any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *  $Revision: 3132 $
 */
package aspecto;

import ext.EventDispatchThreadHangMonitor;
import ext.services.lastfm.AudioScrobblerService;
import ext.services.lastfm.Submitter;
import ext.services.lastfm.SubmitterException;
import org.jajuk.base.DirectoryManager;
import org.jajuk.util.log.Log;
import org.jajuk.base.*;
import org.jajuk.util.*;
import org.jajuk.ui.actions.*;
import org.jajuk.ui.perspectives.*;
import org.jajuk.services.tags.*;
import org.jajuk.services.players.*;
import org.jajuk.ui.helpers.*;
import org.jajuk.base.Collection;
import org.jajuk.base.Device;
import org.jajuk.base.Directory;
import org.jajuk.base.File;
import org.jajuk.base.Playlist;
import org.jajuk.ui.thumbnails.ThumbnailsMaker;
import org.jajuk.ui.widgets.InformationJPanel;
import org.jajuk.services.dj.DigitalDJManager;
import ext.EventDispatchThreadHangMonitor.HangChecker;
import org.jajuk.util.DownloadManager;
import org.jajuk.util.ITechnicalStrings;
import org.jajuk.util.Messages;
import org.jajuk.services.lyrics.*;
import java.security.NoSuchAlgorithmException;
import java.util.ConcurrentModificationException;
import java.util.HashMap;
import java.util.regex.PatternSyntaxException;
import org.jajuk.util.error.*;
import org.jajuk.services.events.*;
import org.jajuk.services.players.FIFO;
import org.jajuk.services.webradio.WebRadioManager;
import org.jajuk.ui.views.*;
import org.jajuk.services.lyrics.providers.GenericProvider;
import org.jajuk.services.lyrics.providers.LyrcProvider;
import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.awt.AWTException;
import java.awt.Image;
import org.jajuk.ui.widgets.*;
import org.jajuk.services.lastfm.*;
import ext.services.lastfm.*;
import ext.services.network.*;
import org.jajuk.services.bookmark.*;
import org.jajuk.services.core.*;
import org.jajuk.services.covers.*;
import java.util.jar.*;
import org.jajuk.util.ConfigurationManager;
import org.jajuk.services.dj.*;
import ext.SwingWorker;

/**
 * 
 */
privileged public aspect LogAspect {

  pointcut logJajukException(JajukException je):
    handler(JajukException) && args(je) && !within(AbstractTableView) && !within(FilesTreeView);

  before(JajukException je): logJajukException(je){
    Log.error(je);
  }

  pointcut logJajukExceptionWithCode(JajukException je):
    handler(JajukException) && args(je) && within(AbstractTableView);

  before(JajukException je): logJajukExceptionWithCode(je){
    Log.error("104",je);
  }

  pointcut logThrowableException(Throwable te):
    handler(Throwable) && args(te) && !within(FIFO) && !within(EntaggedTagImpl);

  before(Throwable te): logJajukExceptionWithCode(te){
    Log.error(te);
  }

  pointcut logThrowableExceptionWithCode(Throwable te):
    handler(Throwable) && args(te) && within(FIFO);

  before(Throwable te): logThrowableExceptionWithCode(te){
    Log.error(122, te);
  }

  pointcut logConcurrentModificationException(ObserverRegistry or):
    handler(ConcurrentModificationException) && this(or);

  before(ObserverRegistry or): logConcurrentModificationException(or){
    Log.debug("Concurrent exception for subject: " + or.subject + " on observer: " + or.obs);
  }

  pointcut logPatternSyntaxException(PatternSyntaxException pse):
    handler(PatternSyntaxException) && args(pse) && !within(Filter);

  before(PatternSyntaxException pse): logPatternSyntaxException(pse){
    Log.error(pse);
  }

  pointcut logPatternSyntaxExceptionWithDebug():
    handler(PatternSyntaxException) && within(Filter);

  before(): logPatternSyntaxExceptionWithDebug(){
    Log.debug("Wrong regexp pattern: " + Filter.checked);
  }

  pointcut logMalformedURLException(MalformedURLException mfue):
    handler(MalformedURLException) && args(mfue) && !within(GenericProvider) && !within(LyrcProvider);

  before(MalformedURLException mfue): logMalformedURLException(mfue){
    Log.error(mfue);
  }

  pointcut logMalformedURLExceptionGenericProvider(GenericProvider gp):
    handler(MalformedURLException) && within(GenericProvider) && this(gp);

  before(GenericProvider gp): logMalformedURLExceptionGenericProvider(gp){
    Log.warn("Invalid lyrics provider [" + gp.querySource + "]");
  }

  pointcut logMalformedURLExceptionLyricProvider(LyrcProvider lp):
    handler(MalformedURLException) && within(LyrcProvider) && this(lp);

  before(LyrcProvider lp): logMalformedURLExceptionLyricProvider(lp){
    Log.warn("Invalid lyrics source URL [" + lp.suggestionURL + "]");
  }

  pointcut logIOException(IOException ioe):
    handler(IOException) && args(ioe) && (within(Device) || withincode(* Playlist.load(..))) && !within(LyricsService);

  before(IOException ioe): logIOException(ioe){
    Log.error(ioe);
  }

  pointcut logIOExceptionLyricsService():
    handler(IOException) && within(LyricsService);

  before(): logIOExceptionLyricsService(){
    Log.warn("IO Exception while loading " + ITechnicalStrings.FILE_LYRICS_CONF_PATH);
  }

  pointcut logFileNotFoundException():
    handler(FileNotFoundException) && within(LyricsService);

  before(): logIOExceptionLyricsService(){
    Log.warn("IO Exception while loading " + ITechnicalStrings.FILE_LYRICS_CONF_PATH);
  }

  pointcut logNoSuchAlgorithmException(NoSuchAlgorithmException ae):
    handler(NoSuchAlgorithmException) && args(ae) && within(MD5Processor);

  before(NoSuchAlgorithmException ae): logNoSuchAlgorithmException(ae){
    Log.error(ae);
  }

  pointcut logJajukSystray(AWTException awt):
    handler(AWTException) && args(awt) && within(JajukSystray);

  before(AWTException awt): logJajukSystray(awt){
    Log.error(awt);
  }

  pointcut logSubmitterException(SubmitterException se):
    handler(SubmitterException) && args(se) && within(LastFmManager);

  before(SubmitterException se): logSubmitterException(se){
    Log.error(se);
  }

//AudioScrobblerService
  pointcut logAudioScrobblerServiceGetAlbum():
    handler(Exception) && withincode(* AudioScrobblerService.getAlbum(..));

  before() : logAudioScrobblerServiceGetAlbum(){
    Log.debug("No info found for artist " + AudioScrobblerService.artist + " this.album " + AudioScrobblerService.album);
  }

  pointcut logAudioScrobblerServiceGetAlbumList():
    handler(Exception) && withincode(* AudioScrobblerService.getAlbumList(..));

  before() : logAudioScrobblerServiceGetAlbumList(){
    Log.debug("No info found for artist " + AudioScrobblerService.artist);
  }
  pointcut logAudioScrobblerServiceGetSimilarArtists():
    handler(Exception) && withincode(* AudioScrobblerService.getSimilarArtists(..));

  before() : logAudioScrobblerServiceGetSimilarArtists(){
    Log.debug("No info found for similar artists to artist " + AudioScrobblerService.artist);
  }

  pointcut logAudioScrobblerServiceGetArtistTopTag():
    handler(Exception) && withincode(* AudioScrobblerService.getArtistTopTag(..));

  before() : logAudioScrobblerServiceGetArtistTopTag(){
    Log.debug("No tag found for artist " + AudioScrobblerService.artist);
  }

  pointcut logAudioScrobblerServiceGetImageAlbum():
    handler(Exception) && withincode(* AudioScrobblerService.getImage(AudioScrobblerAlbum));

  before() : logAudioScrobblerServiceGetImageAlbum(){
    Log.debug("No image found for album " + AudioScrobblerService.album);
  }

  pointcut logAudioScrobblerServiceGetImageArtist():
    handler(Exception) && withincode(* AudioScrobblerService.getImage(AudioScrobblerArtist));

  before() : logAudioScrobblerServiceGetImageArtist(){
    Log.debug("No image found for artist " + AudioScrobblerService.artist);
  }

  pointcut logAudioScrobblerServiceGetImageSimilarArtists():
    handler(Exception) && withincode(* AudioScrobblerService.getImage(AudioScrobblerSimilarArtists));

  before() : logAudioScrobblerServiceGetImageSimilarArtists(){
    Log.debug("No image found for similar artist " + AudioScrobblerService.artist);
  }

  pointcut logAudioScrobblerServiceGetSmallImage():
    handler(Exception) && withincode(* AudioScrobblerService.getSmallImage(AudioScrobblerAlbum));

  before() : logAudioScrobblerServiceGetSmallImage(){
    Log.debug("No small image found for album " + AudioScrobblerService.album);
  }

  //Collection
  pointcut logCollectionCommit():
    execution(* Collection.commit(..)) ;

  after() : logCollectionCommit(){
    Log.debug("Collection commited in " + (System.currentTimeMillis() - Collection.lTime) + " ms");
  }

  public void Collection.endDocument() {
    Log.debug("Collection file parsing done : " +  (System.currentTimeMillis() - Collection.lTime) + " ms");
  }

  public void Collection.startDocument() {
    Log.debug("Starting collection file parsing...");
  }

  //Submitter
  pointcut logSubmitterSubmitTrack(Track track, long secondsPlayed):
    execution(* Submitter.submitTrack(Track,long)) && args(track,secondsPlayed) ;

  void around(Track track, long secondsPlayed) : logSubmitterSubmitTrack(track,secondsPlayed){
    if (Submitter.user == null || Submitter.user.equals("")) {
      Log.debug("Don't submit to Last.fm. Empty user");
    }
    else if (Submitter.password == null || Submitter.password.equals("")) {
      Log.debug("Don't submit to Last.fm. Empty password");
    }
    else if (track.getAuthor().isUnknown()) {
      Log.debug("Don't submit to Last.fm. Unknown Artist");
    }
    else if (track.getName().trim().equals("")) {
      Log.debug("Don't submit to Last.fm. Unknown Title");
    }
    else if(track.getDuration() < 30) {
      Log.debug("Don't submit to Last.fm. Lenght < 30");
    }
    else{
      Log.info("Submitting song to Last.fm: " + track.getName() + " " + secondsPlayed + " secs");
      proceed(track,secondsPlayed);
    }
  }

  //NetworkUtils
  pointcut logNetworkUtilsGetConnection(URL url):
    execution(* NetworkUtils.getConnection(URL,..)) && args(url,..) ;

  before(URL url): logNetworkUtilsGetConnection(url){
    Log.debug("Opening Connection With: {{" + url + "}}");
  }

  //EventDispatchThreadHangMonitor.HangChecker

  pointcut logHangCheckerReportHang():
    execution(* HangChecker.reportHang());

  void around(): logHangCheckerReportHang(){
    if (!EventDispatchThreadHangMonitor.reportedHang) {
      Log.debug("--- event dispatch thread stuck processing event for " + EventDispatchThreadHangMonitor.timeSoFar() + " ms:");
      proceed();
    }
  }


  public void HangChecker.printStackTrace(StackTraceElement[] stackTrace) {
    final String ourEventQueueClassName = EventDispatchThreadHangMonitor.class.getName();
    for (StackTraceElement stackTraceElement : stackTrace) {
      if (stackTraceElement.getClassName().equals(ourEventQueueClassName)) {
        return;
      }
      Log.debug("    " + stackTraceElement);
    }
  }

  pointcut logEventDispatchThreadHangMonitorPostDispatchEvent():
    execution(* EventDispatchThreadHangMonitor.postDispatchEvent());

  before(): logEventDispatchThreadHangMonitorPostDispatchEvent(){
    if (!EventDispatchThreadHangMonitor.reportedHang) {
      Log.debug("--- event dispatch thread unstuck after " + EventDispatchThreadHangMonitor.timeSoFar() + " ms.");
    }
  }

  //Bookmarks
  pointcut logBookmarksAddFiles(Exception e):
    handler(Exception) && args(e) && within(Bookmarks);

  before(Exception e) : logBookmarksAddFiles(e){
    Log.error(e);
  }

  //History
  pointcut logHistoryUpdate(Exception e):
    handler(Exception) && args(e) && withincode(* History.update(..));

  before(Exception e) : logHistoryUpdate(e){
    Log.error(e);
  }

  pointcut logHistoryLoad():
    handler(Exception) && withincode(* History.load(..));

  before() : logHistoryLoad(){
    Log.error(new JajukException(119));
    try {
      History.commit(); // this history looks corrupted, write a void one
    } catch (Exception e) {
      Log.error(e);
    }
  }

  pointcut logHistoryStartElement(Object arg):
    call(* HashMap.get(Object)) && args(arg) && withincode(* History.startElement(..));

  after(Object arg) : logHistoryStartElement(arg){
    Log.debug("upload:" + arg);
  }

  public void History.startDocument() {
    Log.debug("Starting history file parsing...");
  }

  public void History.endDocument() {
    Log.debug("History file parsing done");
  }

  //ExitService
  pointcut logExitServiceRun():
    execution(* ExitService.run());

  before() : logExitServiceRun(){
    Log.debug("Exit Hook begin");
  }

  pointcut logExitServiceExit(int ec):
    execution(* ExitService.exit(int)) && args(ec);

  before(int ec) : logExitServiceExit(ec){
    Log.debug("Exit with code: " + ec);
  }

  //Cover
  pointcut logCoverGetImage():
    execution(Image Cover.getImage());

  after() : logCoverGetImage(){
    Log.debug("Loaded {{" + Cover.url.toString() + "}} in  " + (System.currentTimeMillis() - Cover.l) + " ms");
  }
//DigitalDJManager
  pointcut logDigitalDJManagerCommit(Exception e):
    handler(Exception)&& args(e)&& withincode(* DigitalDJManager.commit(DigitalDJ));

  before(Exception e) : logDigitalDJManagerCommit(e){
    Log.error(145, (DigitalDJManager.dDj != null) ? "{{" + DigitalDJManager.dDj.getName() + "}}" : null, e);
  }

  //debug

  //Device
  pointcut logDeviceCleanRemovedFiles():
    execution(public boolean cleanRemovedFiles());

  after() : logDeviceCleanRemovedFiles(){
    Log.debug("Old file references cleaned in: " + ((Device.l < 1000) ? Device.l + " ms" : Device.l / 1000 + " s"));
  }

  pointcut logDeviceRefreshCommand(Device d):
    call(* DirectoryManager.getElementCount()) && this(d) && withincode(* Device.refreshCommand(..));

  after(Device d) : logDeviceRefreshCommand(d){
    if (Device.sbDeepScan && Log.isDebugEnabled()) {
      Log.debug("Starting refresh of device : " + d);
    }
  }

  pointcut logDeviceSynchronizeCommand(String s):
    call(* InformationJPanel.setMessage(String,..)) && args(s,..) && withincode(* Device.synchronizeCommand(..));

  after(String s) : logDeviceSynchronizeCommand(s){
    Log.debug(s);
  }

  //ItemManager
  pointcut logItemManagerChangeItem(Item itemToChange, String sKey, Object oValue):
    execution(Item ItemManager.changeItem(Item, String, Object,..)) && args(itemToChange,sKey,oValue,..);

  before(Item itemToChange, String sKey, Object oValue) : logItemManagerChangeItem(itemToChange, sKey, oValue){
    if (Log.isDebugEnabled()) {
      Log.debug("Set " + sKey + "=" + oValue.toString() + " to " + itemToChange);
    }
  }

  pointcut logPropertyMetaInformation(ClassNotFoundException e):
    handler(ClassNotFoundException) && args(e) && withincode(PropertyMetaInformation.new(..));

  before(ClassNotFoundException e) : logPropertyMetaInformation(e){
    Log.debug("Class not supported !!!");
  }

  //WebRadioManager
  pointcut logWebRadioManagerDownloadRepository(Exception e):
    handler(Exception) && args(e) && withincode(* WebRadioManager.downloadRepository());

  before(Exception e) : logWebRadioManagerDownloadRepository(e){
    Log.error(e);
    Log.debug("Try download default radio stations from jajuk.info");
    try {
      DownloadManager.download(new URL(WebRadioManager.URL_DEFAULT_WEBRADIOS_2), WebRadioManager.fwebradios);
    } catch (Exception e2) {
      Log.error(e2);
    }
  }
  //ThumbnailsMaker
  pointcut logThumbnailsMakerLaunchAllSizes():
    execution(* ThumbnailsMaker.launchAllSizes(..));

  before() : logThumbnailsMakerLaunchAllSizes(){
    if (ThumbnailsMaker.bAlreadyRunning) {
      Log.debug("Thumb maker already running, leaving");
    }
  }
  pointcut logThumbnailsMakerLaunchProcessus():
    execution(* ThumbnailsMaker.launchProcessus(..));

  after() : logThumbnailsMakerLaunchProcessus(){
    Log.debug("Use command:" + ThumbnailsMaker.commands);
  }

  pointcut logThumbnailsMakerBuildThumbs():
    execution(* ThumbnailsMaker.buildThumbs(..));

  before(): logThumbnailsMakerBuildThumbs(){
    Log.getInstance();
    Log.setVerbosity(Log.FATAL);
  }
  after() : logThumbnailsMakerBuildThumbs(){
    Log.setVerbosity(Log.DEBUG);
    Log.debug("[Thumb maker] " + ThumbnailsMaker.stat + " thumbs created for size: " + ThumbnailsMaker.size + " in "
        + (System.currentTimeMillis() - ThumbnailsMaker.lTime) + " ms");
  }

  //AnimationView
  pointcut logAnimationViewComponentResized():
    execution(* AnimationView.componentResized(..));

  after(): logAnimationViewComponentResized(){
    Log.debug("View resized, new width=" + AnimationView.iSize);
  }

  //CoverView
  pointcut logCoverViewComponentResized():
    execution(* CoverView.componentResized(..));

  before(): logCoverViewComponentResized(){
    Log.debug("Cover resized");
  }
  pointcut logCoverViewDisplayCover():
    handler(Exception) && withincode(* CoverView.displayCover(..));

  before(): logCoverViewDisplayCover(){
    Log.debug("jl=" + CoverView.jl + " url={{" + CoverView.url + "}}");
  }
  pointcut logCoverViewPrepareDisplay(int index):
    execution(Object CoverView.prepareDisplay(int)) && args(index);

  before(int index): logCoverViewPrepareDisplay(index){
    Log.debug("display index: " + index);
  }

  //InformationJPanel
  pointcut logCoverViewSetCurrentTimeMessage(Exception e):
    handler(Exception) && args(e) && withincode(public void InformationJPanel.setCurrentTimeMessage(..));

  before(Exception e): logCoverViewSetCurrentTimeMessage(e){
    Log.debug(e);
  }

  //ConfigurationManager

  pointcut logConfigurationManagerSetDefaultProperty(String arg):
    execution(void ConfigurationManager.setDefaultProperty(String)) && args(arg);

  before(String arg): logConfigurationManagerSetDefaultProperty(arg){

    if(ConfigurationManager.defaults.get(arg) == null) {
      Log.debug("Cannot reset thsi property: " + arg);
    }
  }

  pointcut logUpgradeManagerCheckForUpdate(Exception e):
    handler(Exception) &&args(e)&& withincode(* UpgradeManager.checkForUpdate(..));

  before(Exception e): logUpgradeManagerCheckForUpdate(e){
    Log.debug("Cannot check for updates", e);
  }

  public void RefreshReporter.refreshDone() {
    long refreshTime = System.currentTimeMillis() - RefreshReporter.lRefreshDateStart;
    String message = buildFinalMessage(refreshTime);
    Log.debug(message);
  }

  //Util
  pointcut logUtilCopy(java.io.File file,java.io.File fNew):
    execution(void Util.copy(java.io.File,java.io.File)) && args(file,fNew);

  before(java.io.File file,java.io.File fNew): logUtilCopy(file,fNew){
    Log.debug("Copying: " + file.getAbsolutePath() + "  to : " + fNew.getAbsolutePath());
  }
  pointcut logUtilCopy2(java.io.File file,String sNewName):
    execution(* Util.copy(java.io.File,String)) && args(file,sNewName);

  before(java.io.File file,String sNewName): logUtilCopy2(file,sNewName){
    Log.debug("Renaming: " + file.getAbsolutePath() + "  to : " + sNewName);
  }
  pointcut logUtilCopyToDir(java.io.File file,java.io.File directory):
    execution(* Util.copyToDir(java.io.File,java.io.File)) && args(file,directory);

  before(java.io.File file,java.io.File directory): logUtilCopyToDir(file,directory){
    Log.debug("Copying: " + file.getAbsolutePath() + "  to : " + directory.getAbsolutePath());
  }

  pointcut logUtilDeleteDir(java.io.File dir):
    execution(* Util.deleteDir(java.io.File)) && args(dir);

  before(java.io.File dir): logUtilDeleteDir(dir){
    Log.debug("Deleting: " + dir.getAbsolutePath());
  }
  pointcut logUtilDeleteFile(java.io.File file):
    execution(* Util.deleteFile(java.io.File)) && args(file);

  before(java.io.File file): logUtilDeleteFile(file){
    Log.debug("Deleting: " + file.getAbsolutePath());
  }

  pointcut logUtilExtractFile(java.io.File file):
    call(JarFile.new(java.io.File)) && args(file) && withincode(* Util.extractFile(..));

  before(java.io.File file): logUtilExtractFile(file){
    Log.debug("Open jar: " + file.getAbsolutePath());
  }
  
  pointcut startElement(Collection c) : 
    cflow(call(int Integer.parseInt(..))) && withincode(void Collection.startElement(..)) && handler(Exception) && this(c);

  before(Collection c): startElement(c){
    if (Log.isDebugEnabled()) {
      // wrong format
      Log.debug(Messages.getString("Error.137") + ":" + c.sTrackName);
    }
  }

  pointcut removeDirectory(Directory dir) : 
    execution(void DirectoryManager.removeDirectory(Directory)) && args(dir) && cflow(execution(boolean Device.cleanRemovedFiles()));

  after(Directory dir) : removeDirectory(dir){
    Log.debug("Removed: " + dir);
  }

  pointcut removeFile(File file) : 
    execution(void FileManager.removeFile(File)) && args(file) && cflow(execution(boolean Device.cleanRemovedFiles()));

  after(File file) : removeFile(file){
    Log.debug("Removed: " + file);
  }

  pointcut removePlaylistManager(Playlist playlist) : 
    execution(void PlaylistManager.removePlaylistFile(Playlist)) && args(playlist) && cflow(execution(boolean Device.cleanRemovedFiles()));

  after(Playlist playlist) : removePlaylistManager(playlist){
    Log.debug("Removed: " + playlist);
  }

  pointcut sync(Device c) : 
    execution(void Device.synchronize(..)) && this(c);

  void around(Device c) : sync(c) {
    try {
      proceed(c);
    }
    catch(Exception e){
      Log.error(11, "{{" + c.getName() + "}}", e); // mount failed
      Messages.showErrorMessage(11, c.getName());
      return;
    }
  }
  /*  
  pointcut addFileInRegisterFile(Directory d,File f, String a, String b) :
    cflow(execution(File FileManager.registerFile(String,String,Directory,..))) && (call(void Directory.addFile(File))) && args(a,b,d,..) && args(f);

  before(Directory d,File f, String a, String b) : addFileInRegisterFile(d,f,a,b){

  }*/

  pointcut logEmAction(Exception e) : 
    handler(Exception) && args(e) && (
        within(ActionBase) || 
        withincode(void PerspectiveAdapter.load()) ||
        withincode(boolean Device.refreshCommand(..)) ||
        withincode(void Device.synchronizeCommand()) ||
        withincode(void Playlist.addFiles(..)) ||
        withincode(void DeviceManager.refreshAllDevices()) ||
        withincode(void FIFO.play*()) ||
        withincode(void FIFO.push(..)) ||
        withincode(void FIFO.pushCommand(..)) ||
        withincode(void JavaLayerPlayerImpl.seek(..)) ||
        withincode(void JavaLayerPlayerImpl.progress(..)) ||
        withincode(void MPlayerPlayerImpl.ReaderThread.run()) ||
        withincode(void Player.mute(..)) ||
        withincode(void Player.pause(..)) ||
        withincode(void Player.resume(..)) ||
        withincode(void WebRadioManager.loadRepository()) ||
        withincode(void WebRadioManager.downloadRepository()) ||
        withincode(void WebRadioManager.startElement(..)) ||
        withincode(void ExitAction.perform(..)) ||
        withincode(void DigitalDJFactory.getFactory(..)) ||
        withincode(void LaunchInBrowserAction.perform(..)) ||
        withincode(void NewFolderAction.perform(..)) ||
        withincode(void RefactorAction.refactor(..)) ||
        withincode(void FontManager.setDefaultFont()) ||
        withincode(boolean PlaylistEditorTransferHandler.importData(..)) ||
        withincode(String Item.getHumanValue(..)) ||
        withincode(void QualityAction.perform(..)) ||  
        withincode(void Playlist.commit(..)) ||  
        withincode(void SaveAsAction.perform(..)) ||  
        
        
        
        withincode(ITagImpl Type.getTagImpl())
    );

  before(Exception e) : logEmAction(e){
    Log.error(e);
  }
  
  pointcut parseLog(String arg):
    call(* *.parse*(String)) && args(arg) && within(ConfigurationManager);
  
  after(String arg) throwing(Exception e): parseLog(arg){
    Log.debug("Cannot parse property: " + arg);
    Log.debug(e);
  }
  
 declare soft : InterruptedException : threadJoinLogAspect();
  
  pointcut threadJoinLogAspect():
    call(* *.join(..)) && !within(SwingWorker);
  
  void around(): threadJoinLogAspect(){
    try{
      proceed();
    }
    catch(InterruptedException e){
      Log.error(e);
    }
  }
  
  pointcut threadSleepAspect():
    call(* Thread.sleep(..));
  
  declare soft : InterruptedException : threadSleepAspect();
  
  void around(): threadSleepAspect(){
    try{
      proceed();
    }
    catch(InterruptedException e){
      Log.error(e);
    }
  }
}
